<!-- 控件视图-可调整大小 -->
<template>
    <div ref="resizableDom" class="widget-view-resizable">
        <div v-if="resizable.left && resizable.top && resizable.height && resizable.width" class="resizable-handle handle-nw" data-event="left-top" @mousedown.stop="onResizable" @click.stop="onClick" />
        <div v-if="resizable.width && resizable.top && resizable.height" class="resizable-handle handle-ne" data-event="right-top" @mousedown.stop="onResizable" @click.stop="onClick" />
        <div v-if="resizable.left && resizable.height && resizable.width" class="resizable-handle handle-sw" data-event="left-bottom" @mousedown.stop="onResizable" @click.stop="onClick" />
        <div v-if="resizable.width && resizable.height" class="resizable-handle handle-se" data-event="right-bottom" @mousedown.stop="onResizable" @click.stop="onClick" />
        <div v-if="resizable.left && resizable.width" class="resizable-handle handle-w" data-event="left" @mousedown.stop="onResizable" @click.stop="onClick" />
        <div v-if="resizable.top && resizable.height" class="resizable-handle handle-n" data-event="top" @mousedown.stop="onResizable" @click.stop="onClick" />
        <div v-if="resizable.width" class="resizable-handle handle-e" data-event="right" @mousedown.stop="onResizable" @click.stop="onClick" />
        <div v-if="resizable.height" class="resizable-handle handle-s" data-event="bottom" @mousedown.stop="onResizable" @click.stop="onClick" />
    </div>
</template>

<script>
import { defineComponent, toRefs, ref } from 'vue'
import useWidget from '@/libs/edit/widgetData'
import usePhoneZoom from '@/libs/edit/phoneZoom'
export default defineComponent({
    name: 'WidgetViewResizable',
    props: {
        // 控件数据
        element: {
            type: Object,
            default: () => ({})
        },
        // 当前left值，在 position 为绝对定位时有效
        left: {
            type: Number,
            default: 0
        },
        // 当前top值，在 position 为绝对定位时有效
        top: {
            type: Number,
            default: 0
        },
        // 当前宽度值
        width: {
            type: Number,
            default: 0
        },
        // 当前高度值
        height: {
            type: Number,
            default: 0
        },
        // 可调整最小宽度值
        minWidth: {
            type: Number,
            default: 10
        },
        // 可调整最小高度值
        minHeight: {
            type: Number,
            default: 10
        },
        // 可调整最大宽度值
        maxWidth: {
            type: Number,
            default: Infinity
        },
        // 可调整最大高度值
        maxHeight: {
            type: Number,
            default: Infinity
        },
        // 设置可调整的属性
        resizable: {
            type: Object,
            default: () => ({
                left: true,
                top: true,
                width: true,
                height: true
            })
        }
    },
    emits: [
        'update:left',
        'update:top',
        'update:width',
        'update:height',
        'start', // 按下调整手柄时触发
        'move', // 拖动调整手柄时触发
        'end', // 松开调整手柄时触发
        'click' // 点击调整手柄时触发
    ],
    setup(props, { emit }) {
        const {
            element,
            left, top,
            width, height,
            minWidth, minHeight,
            maxWidth, maxHeight,
            resizable
        } = toRefs(props)

        const {
            onClickWidget
        } = useWidget()

        const {
            getZoomNum
        } = usePhoneZoom()

        const resizableDom = ref(null)

        const onResizable = e => {
            const eventName = e.target.dataset.event
            emit('start', eventName)

            // 鼠标开始点击位置
            const { clientX: mouseX, clientY: mouseY } = e

            // dom开始属性值
            const domW = width.value
            const domH = height.value
            const domL = left.value
            const domT = top.value

            // 更新后dom属性值
            let newDomW = domW
            let newDomH = domH
            let newDomL = domL
            let newDomT = domT

            let dragStatus = false
            document.onmousemove = event => {
                dragStatus = true
                // 宽高最小值
                const minW = minWidth.value
                const minH = minHeight.value
                // 宽高最大值
                const maxW = maxWidth.value
                const maxH = maxHeight.value

                const offsetX = getZoomNum(event.pageX - mouseX)
                const offsetY = getZoomNum(event.pageY - mouseY)

                const updateDomL = () => {
                    if (!resizable.value.left) return
                    newDomL = domL + offsetX
                    if (newDomL >= domL + domW - minW) {
                        newDomL = domL + domW - minW
                    } else if (newDomL <= 0) {
                        newDomL = 0
                        return
                    }
                    updateDomW(2)
                }
                const updateDomT = () => {
                    if (!resizable.value.top) return
                    newDomT = domT + offsetY
                    if (newDomT >= domT + domH - minH) {
                        newDomT = domT + domH - minH
                    } else if (newDomT <= 0) {
                        newDomT = 0
                        return
                    }
                    updateDomH(2)
                }
                const updateDomW = (type = 1) => {
                    if (!resizable.value.width) return
                    newDomW = domW + (type === 2 ? -offsetX : offsetX)
                    if (newDomW <= minW) {
                        newDomW = minW
                    } else if (newDomW + newDomL >= maxW) {
                        newDomW = maxW - newDomL
                    }
                }
                const updateDomH = (type = 1) => {
                    if (!resizable.value.height) return
                    newDomH = domH + (type === 2 ? -offsetY : offsetY)
                    if (newDomH <= minH) {
                        newDomH = minH
                    } else if (newDomH + newDomT >= maxH) {
                        newDomH = maxH - newDomT
                    }
                }

                switch (eventName) {
                    case 'right':
                        updateDomW()
                        break
                    case 'bottom':
                        updateDomH()
                        break
                    case 'left':
                        updateDomL()
                        break
                    case 'top':
                        updateDomT()
                        break
                    case 'right-bottom':
                        updateDomW()
                        updateDomH()
                        break
                    case 'right-top':
                        updateDomW()
                        updateDomT()
                        break
                    case 'left-bottom':
                        updateDomL()
                        updateDomH()
                        break
                    case 'left-top':
                        updateDomL()
                        updateDomT()
                        break
                
                    default:
                        break
                }

                // 更新视图数据
                if (resizable.value.left) emit('update:left', newDomL)
                if (resizable.value.width) emit('update:width', newDomW)
                if (resizable.value.top) emit('update:top', newDomT)
                if (resizable.value.height) emit('update:height', newDomH)

                emit('move', {
                    left: newDomL,
                    top: newDomT,
                    width: newDomW,
                    height: newDomH
                })
            }

            document.onmouseup = () => {
                emit('end', {
                    left: newDomL,
                    top: newDomT,
                    width: newDomW,
                    height: newDomH
                })
                dragStatus = false
                document.onmousemove = null
                document.onmouseup = null
            }
        }

        const onClick = e => {
            if (!!element.value?.eles?.id) onClickWidget(e, element.value.eles.id)
            emit('click', e)
        }

        return {
            resizableDom,
            resizable,
            onResizable,
            onClick
        }
    }
})
</script>

<style lang="less" scoped>
@import './widget-view-resizable.less';
</style>